package cn.edu.ctbu.jpatest.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

/**
 * @author xiaopeng
 * @version 1.0
 */
@Component
@Aspect
@Slf4j
public class HttpAspect {

    @Pointcut("execution(public * cn.edu.ctbu.jpatest.api.StudentApiController.*(..))")
    public void log() {
    }

    @Before("log()")
    public void doBefore() {
        log.info("doBefore");
    }

    @After("log()")
    public void doAfter() {
        log.info("doAfter");
    }

    /**
     * 在AfterReturning中，我们可以访问到方法的返回值
     * 在After之前执行
     * @param object
     */
    @AfterReturning(returning = "object", pointcut = "log()")
    public void doAfterReturning(Object object) {
        log.info("response={}", object.toString());
    }

    /**
     * 获取方法的执行耗时
     * 环绕通知，可以自定义执行顺序
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("log()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        Object object = joinPoint.proceed(joinPoint.getArgs());
        stopWatch.stop();
        long totalTimeMillis = stopWatch.getTotalTimeMillis();
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();

        String methodName = signature.getDeclaringTypeName() + "." + signature.getName();
        log.info("methodName={},time={}", methodName, totalTimeMillis);
        return object;
    }
}
